home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / lang / PPCSmllEiffel.lha / PPCSmallEiffel / lib_se / jvm.e < prev    next >
Text File  |  1998-01-16  |  20KB  |  885 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class JVM
  17.    --
  18.    -- Handling of Java Virtual Machine byte code generation.
  19.    --
  20.  
  21. inherit CODE_PRINTER;
  22.  
  23. creation make 
  24.  
  25. feature
  26.  
  27.    output_name: STRING;
  28.      -- This name is used as the name of the main output class 
  29.      -- file and as the name of the directory used to store
  30.      -- auxilliary class files.
  31.    
  32. feature {NONE}
  33.  
  34.    b_put_u1_count: INTEGER;
  35.      -- To count printed bytes.
  36.  
  37. feature {NONE}
  38.  
  39.    make is do end;
  40.  
  41. feature {NONE}
  42.  
  43.    fields: FIXED_ARRAY[RUN_FEATURE] is
  44.       once 
  45.      !!Result.with_capacity(4);
  46.       end;
  47.  
  48.    methods: FIXED_ARRAY[RUN_FEATURE] is
  49.       once 
  50.      !!Result.with_capacity(64);
  51.       end;
  52.  
  53. feature {RUN_FEATURE}
  54.  
  55.    add_field(rf: RUN_FEATURE) is
  56.       require
  57.      rf /= Void;
  58.      not fields.fast_has(rf)
  59.       do
  60.      fields.add_last(rf);
  61.       ensure
  62.      fields.fast_has(rf)
  63.       end;
  64.  
  65. feature {RUN_FEATURE,NATIVE}
  66.  
  67.    add_method(rf: RUN_FEATURE) is
  68.       require
  69.      rf /= Void;
  70.      not methods.fast_has(rf)
  71.       do
  72.      methods.add_last(rf);
  73.       ensure
  74.      methods.fast_has(rf)
  75.       end;
  76.  
  77. feature 
  78.  
  79.    set_output_name(n: STRING) is
  80.       do
  81.      output_name := n;
  82.       end;
  83.  
  84. feature {SMALL_EIFFEL}
  85.  
  86.    mkdir(root: RUN_FEATURE) is
  87.      -- Create a new directory to store class files.
  88.       require
  89.      root /= Void;
  90.      small_eiffel.is_ready
  91.       do
  92.      if output_name = Void then
  93.         output_name := root.current_type.base_class_name.to_string;
  94.         output_name := output_name.twin;
  95.         output_name.to_lower;
  96.      end;
  97.      if output_name.has_suffix(class_suffix) then
  98.         output_name.remove_suffix(class_suffix);
  99.      end;
  100.      echo.put_string("Trying to prepare directory %"");
  101.      echo.put_string(output_name);
  102.      echo.put_string("%" to store Java byte code.%N");
  103.      file_tools.mkdir(output_name);
  104.       end;
  105.  
  106.    write_jvm_root_class is
  107.       local
  108.      idx: INTEGER;
  109.      cp: like constant_pool;
  110.       do
  111.      cp := constant_pool;
  112.          start_directory(out_file_path,output_name);
  113.          out_file_path.append(fz_jvm_root);
  114.      out_file_path.append(class_suffix);
  115.      bfw_connect(out_file,out_file_path);
  116.      start_basic;
  117.      access_flags := 1025; -- (ACC_PUBLIC,ACC_ABSTRACT)
  118.      this_class_idx := cp.idx_class2(jvm_root_class);
  119.      super_class_idx := cp.idx_java_lang_object;
  120.      -- Fields :
  121.      args_field;
  122.      manifest_string_pool.jvm_define_fields;
  123.      once_routine_pool.jvm_define_fields;
  124.      if run_control.no_check then
  125.         field_info.add(9,cp.idx_uft8(fz_58),cp.idx_uft8(fz_41));
  126.      end;
  127.      -- Methods :
  128.      --    The initialize method :
  129.      current_frame := Void;
  130.      method_info.start(9,fz_28,fz_29);
  131.      manifest_string_pool.jvm_initialize_fields;
  132.      once_routine_pool.jvm_initialize_fields;
  133.      if run_control.no_check then
  134.         idx := cp.idx_fieldref3(jvm_root_class,fz_58,fz_41);
  135.         code_attribute.opcode_iconst_0;
  136.         code_attribute.opcode_putstatic(idx,-1);
  137.      end;
  138.      code_attribute.opcode_return;
  139.      method_info.finish;
  140.      --    For switches :
  141.      switch_collection.jvm_define;
  142.      finish_class;
  143.       end;
  144.  
  145.    write_main_class(rf3: RUN_FEATURE_3) is
  146.      -- Write Java Byte Code for main class to call `rf3'.
  147.       require
  148.      rf3 /= Void;
  149.      small_eiffel.is_ready
  150.       local
  151.      idx: INTEGER;
  152.      cp: like constant_pool;
  153.      ca: like code_attribute;
  154.       do
  155.      cp := constant_pool;
  156.      ca := code_attribute;
  157.      out_file_path.copy(output_name);
  158.      out_file_path.append(class_suffix);
  159.      bfw_connect(out_file,out_file_path);
  160.      start_basic;
  161.      access_flags := 16; -- (ACC_FINAL)
  162.      this_class_idx := cp.idx_class2(output_name);
  163.      super_class_idx := cp.idx_java_lang_object;
  164.      -- Methods :
  165.      --    The main method :
  166.      current_frame := Void;
  167.      method_info.start(9,fz_main,fz_23);
  168.      set_args_field;
  169.      idx := cp.idx_methodref3(jvm_root_class,fz_28,fz_29);
  170.      ca.opcode_invokestatic(idx,0);
  171.      rf3.run_class.jvm_push_default;
  172.      idx := cp.idx_methodref(rf3);
  173.      ca.opcode_invokevirtual(idx,-1);
  174.      ca.opcode_system_out;
  175.      idx := cp.idx_methodref3(fz_25,fz_42,fz_29);
  176.      ca.opcode_invokevirtual(idx,-1);
  177.      ca.opcode_system_err;
  178.      ca.opcode_invokevirtual(idx,-1);
  179.      ca.opcode_return;
  180.      method_info.finish;
  181.      finish_class;
  182.       end;
  183.  
  184. feature {CODE_ATTRIBUTE}
  185.  
  186.    max_locals: INTEGER is
  187.       do
  188.      if current_frame /= Void then
  189.         Result := current_frame.jvm_max_locals;
  190.      else
  191.         Result := 4;
  192.      end;
  193.       end;
  194.  
  195. feature {NONE}
  196.    
  197.    access_flags: INTEGER;
  198.      -- of the class.
  199.  
  200.    this_class_idx: INTEGER;
  201.  
  202.    super_class_idx: INTEGER;
  203.  
  204.    start_basic is
  205.       do
  206.      fields.clear;
  207.      methods.clear;
  208.      constant_pool.clear;
  209.      field_info.clear;
  210.      method_info.clear;
  211.      b_put_u1_count := 0;
  212.       end;
  213.  
  214. feature {RUN_CLASS}
  215.  
  216.    start_new_class(rc: RUN_CLASS) is
  217.       require
  218.      output_name /= Void
  219.       local
  220.      name_idx, type_idx: INTEGER;
  221.      cp: like constant_pool;
  222.       do
  223.      cp := constant_pool;
  224.      start_basic;
  225.      tmp_string.copy(rc.unqualified_name);
  226.      tmp_string.to_lower;
  227.      start_directory(out_file_path,output_name);
  228.      out_file_path.append(tmp_string);
  229.      out_file_path.append(class_suffix);
  230.      bfw_connect(out_file,out_file_path);
  231.      access_flags := 16;
  232.      this_class_idx := rc.fully_qualified_constant_pool_index;
  233.      super_class_idx := cp.idx_jvm_root_class;
  234.      -- <clinit> :
  235.      method_info.start(9,fz_76,fz_29);
  236.      -- generating_type :
  237.      name_idx := cp.idx_uft8(us_generating_type);
  238.      type_idx := cp.idx_eiffel_string_descriptor;
  239.      field_info.add(9,name_idx,type_idx);
  240.      name_idx := cp.idx_fieldref5(this_class_idx,name_idx,type_idx);
  241.      code_attribute.opcode_aconst_null;
  242.      code_attribute.opcode_putstatic(name_idx,-1);
  243.      -- generator :
  244.      name_idx := cp.idx_uft8(us_generator);
  245.      field_info.add(9,name_idx,type_idx);
  246.      name_idx := cp.idx_fieldref5(this_class_idx,name_idx,type_idx);
  247.      code_attribute.opcode_aconst_null;
  248.      code_attribute.opcode_putstatic(name_idx,-1);
  249.      code_attribute.opcode_return;
  250.      method_info.finish;
  251.      rc.jvm_define_class_invariant;
  252.       end;
  253.  
  254.    finish_class is
  255.      -- Really print the class file.
  256.       do
  257.      put_magic;
  258.      put_minor_version;
  259.      put_major_version;
  260.      constant_pool.write_bytes;
  261.      b_put_u2(access_flags);
  262.      b_put_u2(this_class_idx);
  263.      b_put_u2(super_class_idx);
  264.      -- interfaces_count :
  265.      b_put_u2(0);
  266.      field_info.write_bytes;
  267.      method_info.write_bytes;
  268.      -- attributes_count :
  269.      b_put_u2(0);
  270.      out_file.disconnect;
  271.      echo.print_count("byte",b_put_u1_count);
  272.       end;
  273.  
  274. feature
  275.  
  276.    current_frame: RUN_FEATURE;
  277.      -- Current method or current field.
  278.  
  279. feature {RUN_CLASS,SWITCH_COLLECTION}
  280.  
  281.    set_current_frame(cf: like current_frame) is
  282.       do
  283.      current_frame := cf;
  284.       end;
  285.    
  286. feature
  287.  
  288.    argument_offset_of(an: ARGUMENT_NAME): INTEGER is
  289.       require
  290.      an /= Void
  291.       do
  292.      Result := current_frame.jvm_argument_offset(an);
  293.       ensure
  294.      Result >= 0
  295.       end;
  296.  
  297.    local_offset_of(ln: LOCAL_NAME): INTEGER is
  298.       require
  299.      ln /= Void
  300.       do
  301.      Result := current_frame.jvm_local_variable_offset(ln);
  302.       ensure
  303.      Result >= 0
  304.       end;
  305.  
  306.    result_offset: INTEGER is
  307.       do
  308.      Result := current_frame.jvm_result_offset;
  309.       end;
  310.  
  311. feature {CP_INFO}
  312.  
  313.    b_put_u1(byte: CHARACTER) is
  314.       require
  315.      0 <= byte.code;
  316.      byte.code <= 255
  317.       do
  318.      out_file.put_byte(byte);
  319.      b_put_u1_count := b_put_u1_count + 1;
  320.       end;
  321.  
  322. feature {CONSTANT_POOL,FIELD_INFO,METHOD_INFO}
  323.  
  324.    b_put_u2(u2: INTEGER) is
  325.       do
  326.      b_put_u1((u2 // 256).to_character);
  327.      b_put_u1((u2 \\ 256).to_character);
  328.       ensure
  329.      b_